/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package czStvDpds.input;

import czStvDpds.logging.Logging;
import java.util.ArrayList;
import java.util.logging.Level;
import org.lwjgl.input.Keyboard;

/**
 * Stará se o zjišťování vstupů z klávesnice. Běží v samostatném vlákně. Funguje
 * pouze pokud je aktivní okno LWJGL. Pokud není, ukočí se poslouchání.
 *
 * @author divad
 */
public class KeyboardHandler extends Thread {

    private long delay = 20;
    private ArrayList<LWJGLKeyListener> listeners;
    private boolean running;

    /**
     * vytvoří novou instanci a spustí zjišťovací vlákno
     */
    public KeyboardHandler() {
        listeners = new ArrayList<>();
        this.running = false;
//        this.start();
    }

    /**
     * vytvoří novou instanci s předanými posluchači a spustí zjišťovací vlákno
     */
    private KeyboardHandler(ArrayList<LWJGLKeyListener> listeners, long delay) {
        this.listeners = listeners;
        this.delay = delay;
        this.start();
        this.running = true;
    }

    /**
     * Přidá listener do seznamu posluchačů.
     *
     * @param listener
     * @see LWJGLKeyListener
     */
    public void addLWJGLKeyListener(LWJGLKeyListener listener) {
        this.listeners.add(listener);
    }

    /**
     * odebere listener ze seznamu posluchačů
     *
     * @param listener
     * @see LWJGLKeyListener
     */
    public void removeLWJGLKeyListener(LWJGLKeyListener listener) {
        this.listeners.remove(listener);
    }

    /**
     * vrátí pole předaných posluchačů
     *
     * @return
     * @see LWJGLKeyListener
     */
    public ArrayList<LWJGLKeyListener> getLWJGLKeyListeners() {
        return listeners;
    }

    /**
     * Nastaví dobu mezi jednotlivými pokusy o přečtení v stupů v milisekundách
     *
     * @param delay
     */
    public void setDelay(long delay) {
        this.delay = delay;
    }

    /**
     * Vrátí dobu mezi jednotlivými pokusy o přečtení v milisekundách
     *
     * @return
     */
    public long getDelay() {
        return delay;
    }

    /**
     * Ukončí poslouchací vlákno. Toto vlákno již nelze zpětně rozběhnout.
     */
    public void stopListening() {
        this.running = false;
    }

    /**
     * Vrátí nový KeyboardHandler s předanými posluchači
     */
    public KeyboardHandler startListening() {
        this.running = false;
        return new KeyboardHandler(this.listeners, this.delay);
    }

    public void setRepeatEvents(boolean enable) {
        if (Keyboard.isCreated()) {
            Keyboard.enableRepeatEvents(enable);
        }
    }

    public boolean areRepeatEvents() {
        if (Keyboard.isCreated()) {
            return Keyboard.areRepeatEventsEnabled();
        }
        return false;
    }

    /**
     * Čte vstupy z klávesnice a předává je předaným listenerům. Každá akce
     * klávesy má svůj vlastní event.
     */
    @Override
    public void run() {
        while (Keyboard.isCreated() && this.running) {
            while (Keyboard.next()) {
                LWJGLKeyEvent e = new LWJGLKeyEvent(Keyboard.getEventKey(), Keyboard.getEventCharacter(), Keyboard.getEventKeyState(), Keyboard.getEventNanoseconds());
                for (LWJGLKeyListener l : listeners) {
                    l.keyAction(e);
                }
            }
            try {
                this.sleep(delay);
            } catch (InterruptedException ex) {
                Logging.getMainLogger().log(Level.SEVERE, null, ex);
            }
        }
        System.out.println("Key listening terminated");
        this.running = false;
    }

    public boolean isRunning() {
        return running;
    }
}
